package com.xuecheng.content.service.impl;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.xuecheng.basic.api.BasicClient;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.vo.CategoryVo;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.model.vo.TeachplanVo;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.config.MinioTemplate;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.CoursePub;
import com.xuecheng.content.mapper.CoursePubMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.CoursePubService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.content.service.CourseTeacherService;
import com.xuecheng.content.service.TeachplanService;
import com.xuecheng.web.exception.BusinessException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 课程发布 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-09-14
 */
@Service
public class CoursePubServiceImpl extends ServiceImpl<CoursePubMapper, CoursePub> implements CoursePubService {

    @Autowired
    private TeachplanService teachplanService;

    @Autowired
    private CourseBaseService courseBaseService;

    @Autowired
    private BasicClient basicClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private CourseTeacherService courseTeacherService;
    @Override
    public Map preview(Long courseBaseId) {

        // 1.查询课程计划
        ResponseResult responseResult = teachplanService.treeNodes(courseBaseId);
        TeachplanVo teachplanVo = (TeachplanVo) responseResult.getData();

        // 2.准备课程发布对象
        // 2-1 填充课程基本信息
        CourseBase courseBase = courseBaseService.getById(courseBaseId);
        CoursePub coursePub = BeanHelper.copyProperties(courseBase, CoursePub.class);
        // 2-2 填充课程分类名称（mt：大分类，st：小分类）
        String mtName = findCategoryName(coursePub.getMt());
        coursePub.setMtName(mtName);
        String stName = findCategoryName(coursePub.getSt());
        coursePub.setStName(stName);
        // 2-3 课程计划
        coursePub.setTeachplan(JSON.toJSONString(teachplanVo));
        // 2-4 发布时间
        coursePub.setCreateDate(new Date());
        // 2-5 课程价格
        coursePub.setPrice(courseBase.getPrice().longValue());
        // 2-4 教师信息（实战）
        Object teacherList = courseTeacherService.getTeacherListById(courseBaseId).getData();
        coursePub.setTeachers(JSON.toJSONString(teacherList));

        // 3.将数据设置到模型中
        Map model = new HashMap();
        model.put("coursePub",coursePub);
        model.put("teachplanNode",teachplanVo);


        // 4.返回模型
        return model;
    }

    // 根据id查询分类名称
    private String findCategoryName(String categoryId) {
        ResponseResult<CategoryVo> response = basicClient.findById(categoryId);
        if (response.getCode()!=0) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        CategoryVo categoryVo = response.getData();
        String name = categoryVo.getName();
        return name;
    }
    @Autowired
    private AsyncCoursePubService asyncCoursePubService;
    //课程发布
    @Transactional
    @Override
    public ResponseResult publishCourse(Long courseBaseId) throws IOException, TemplateException {

        //1.参数校验
        if ((ObjectUtil.isEmpty(courseBaseId))) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //2.查询课程信息
        CourseBase courseBase = courseBaseService.getById(courseBaseId);
        //3.检验状态
        if ((!StrUtil.equals(courseBase.getAuditStatus(), CourseConstants.AUDIT_PASTED_STATUS))) {
            throw new BusinessException(ErrorCode.MEDIABINDERROR);
        }
        //4.查询coursePub
        Map map = this.preview(courseBaseId);
        CoursePub coursePub = (CoursePub) map.get("coursePub");
        coursePub.setId(courseBaseId);//课程发布ID
        coursePub.setCourseId(courseBaseId);//课程ID

        //5.保存发布的数据
        this.saveOrUpdate(coursePub);

        //6.更新课程状态为已发布
        courseBase.setAuditStatus(CourseConstants.AUDIT_PUBLISHED_STATUS);
        courseBaseService.updateById(courseBase);
        System.out.println(">>>>>>>>>>>>>>"+"主线程");
        //............异步抽取出代码到AsyncCoursePubService
        //7.调用异步上传Minio方法
        asyncCoursePubService.publish(map,coursePub);

        //8.RabbitMQ消息发送
        /**
         * 调用 convertAndSend
         * 参数一：交换机名
         * 参数二：路由规则
         *参数三：消息内容   -直接传coursePub的话由于内容过多，存储压力过大，故存储coursePub的id，后续再查询出内容
         */
        rabbitTemplate.convertAndSend("content.exchange","course.pub",coursePub.getId());

        //9.返回OK
        return ResponseResult.okResult();
    }
}
